
#include "Animation.h"

namespace animationagent {


static const Uint32 DEFAULT_ANIM_RATE = 20;
AnimationSequence::AnimationSequence(char *n) :
    index_array(20)
{
    playstyle = ONCE;
    anim_rate_msec = DEFAULT_ANIM_RATE;
    memcpy(name, n, sizeof(name) - 1);
    name[sizeof(name) - 1] = '\0';
    pindex = 9;
}

AnimationSequence::~AnimationSequence()
{
}

void AnimationSequence::set_frame_rate(Uint32 msec)
{
    anim_rate_msec = msec;
}

void AnimationSequence::set_playstyle(enum AnimationStyle style)
{
    playstyle = style;
}

void AnimationSequence::append_index(Uint16 i)
{
    index_array.append(i);
}

Uint16 AnimationSequence::get_next_frame_index()
{
    pindex ++;
    if (pindex >= index_array.size()) {
        switch (playstyle) {
        case ONCE:
            pindex = index_array.size() - 1;
            break;
        case LOOP:
            pindex = 0;
            break;
        default:
            break;
        }
    }
    return index_array.get(pindex);
}

void AnimationSequence::reset()
{
    pindex = 0;
}

Animation::Animation() :
    Widget(),
    frames(20),
    sequences(10)
{
    init();
}

Animation::Animation(Sint32 frame_num) :
    Widget(),
    frames(frame_num),
    sequences(frame_num / 2)
{
    init();
}

Animation::~Animation()
{
    for (int i=0; i<sequences.size(); i++) {
        delete sequences.get(i);
    }
}

void Animation::init()
{
    anim_oldtime_msec = 0;
    current_frame = 0;
    current_sequence = 0;
}

void Animation::add_frame(SDL_Surface *frame)
{
    //SDL_SetColorKey(frame, flags,
     //               SDL_MapRGB(frame->format, colorkey.r, colorkey.g, colorkey.b));
    //SDL_SetAlpha(frame, flags, alpha);
    frames.append(frame);
}

void Animation::add_sequence(AnimationSequence *seq)
{
    sequences.append(seq);
}

void Animation::draw(SDL_Surface *screen)
{
    if (!visible) {
        return;
    }
    Widget::draw(screen);
}

void Animation::update()
{
    AnimationSequence *seq = sequences.get(current_sequence);
    if (seq == NULL) {
        //use default sequence
        if (anim_oldtime_msec + DEFAULT_ANIM_RATE > SDL_GetTicks() ) {
            return;
        }
        anim_oldtime_msec = SDL_GetTicks();
        current_frame = (current_frame + 1) % frames.size();
    } else {
        //use userdefined sequence
        if (anim_oldtime_msec + seq->anim_rate_msec > SDL_GetTicks() ) {
            return;
        }
        anim_oldtime_msec = SDL_GetTicks();

        current_frame = seq->get_next_frame_index();
    }

    p_surface = frames.get(current_frame);
    Widget::update();
}

void Animation::play(char *name)
{
    int i;
    for (i=0; i<sequences.size(); i++) {
        if (strncmp(sequences.get(i)->name, name, sizeof(sequences.get(i)->name)) == 0) {
            play(i);
            break;
        }
    }
}

void Animation::play(Sint32 seq_index)
{
    if (seq_index >= sequences.size()) {
        return;
    }
    current_sequence = seq_index;
}

void Animation::pause()
{
    //TODO
}

}
